package com.example.menuvirtualclient.repository;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;

import com.example.menuvirtualclient.core.*;
import com.example.menuvirtualclient.data.Repository;

public class OrderDetailRepository extends Repository<OrderDetail>{

	private static final String LOGTAG = "OrderDetailRepository";
	private OrderRepository _orderRepository;
	private DishRepository _dishRepository;
	private CommentRepository _commentRepository;

	public OrderDetailRepository(Context context) {
		super(context);
		_orderRepository = new OrderRepository(context);
		_dishRepository = new DishRepository(context);
		_commentRepository = new CommentRepository(context);
	}

	@Override
	public void Insert(OrderDetail entity) {
		SQLiteDatabase db = null;
		try{
			ContentValues newRow = new ContentValues();
			newRow.put("status", entity.getStatus());
			newRow.put("orderid", entity.getOrder().getId());
			newRow.put("dishid", entity.getDish().getId());
			newRow.put("cookingPoint", entity.getCookingPoint());
			
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();
			db.insert(getTableName(), null, newRow);
			
			int insertId = GetIdentity(db);			
			db.close();
			
			entity.setId(insertId);
		}
		catch(NullPointerException ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		catch(SQLiteException ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		catch(Exception ex){
			Log.e(LOGTAG, ex.getMessage());		
		}
		finally{
			if(db != null)
				if(db.isOpen()) db.close();
		}
	}
	
	private int GetIdentity(SQLiteDatabase db){
		String[] column = new String[] {"seq"};
		Cursor cursor = db.query("sqlite_sequence", column, "name='" + getTableName() + "'", null, null, null, null);
		cursor.moveToFirst();
		int insertId = cursor.getInt(0);
		cursor.close();
		return insertId;
	}
	
	@Override
	public boolean Update(OrderDetail entity) {
		boolean result = false;
		SQLiteDatabase db = null;
		try{
			ContentValues values = new ContentValues();
			values.put("status", entity.getStatus());
			values.put("orderid", entity.getOrder().getId());
			values.put("dishid", entity.getDish().getId());
			values.put("cookingPoint", entity.getCookingPoint());			
			
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();
			int rows = db.update(getTableName(), values, "id = " + entity.getId(), null);			
			result = (rows > 0) ? true : false;
			db.close();
		}		
		catch(SQLiteException ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		catch(Exception ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		finally{
			if(db != null)
				if(db.isOpen()) db.close();
		}
		return result;
	}
	
	@Override
	public OrderDetail Get(long id) {
		SQLiteDatabase db = null;
		OrderDetail entity = null;
		String[] filter = new String[1];
		filter[0] = Long.toString(id);
		try{
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();			
			Cursor cursor = db.rawQuery("SELECT id, orderid, dishid, (strftime('%s',date)*1000), status, cookingPoint FROM Orders_Details WHERE id = ?", filter);
			
			cursor.moveToFirst();
			entity = BuildNewEntity(cursor); 
			cursor.close();
		    db.close();
		}
		catch(Exception ex){
			Log.e(LOGTAG, ex.getMessage());			
		}
		finally{
			if(db != null)
				if(db.isOpen()) {
					db.close();
					Log.e(LOGTAG, "Close database");		
				}
		}
		return entity;
	}
	
	public List<OrderDetail> GetAllByOrder(int id){
		SQLiteDatabase db = null;
		try{
			List<OrderDetail> list = new ArrayList<OrderDetail>();
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();
			Cursor cursor = db.query(getTableName(), null, null, null, null, null, null);
			
			cursor.moveToFirst();
		    while (!cursor.isAfterLast()) {
		    	list.add(BuildNewEntity(cursor));
		    	cursor.moveToNext();
		    }
		    cursor.close();
		    db.close();
		    return list;
		}
		catch(SQLiteException ex){
			Log.e(LOGTAG, ex.getMessage());
			throw ex;
		}		
		finally{
			if(db != null)
				if(db.isOpen()) db.close();
		}
	}
	
	public boolean Delete(int orderId, int dishId) {
		boolean result = false;
		SQLiteDatabase db = null;
		String[] filter = new String[2];
		filter[0] = Long.toString(orderId);
		filter[1] = Long.toString(dishId);
		try{
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();
			int rows = db.delete(getTableName(), " orderid = ? AND dishid = ? ", filter);
			result = (rows > 0) ? true : false;
			db.close();			
		}
		catch (SecurityException ex) {
			Log.e(LOGTAG, ex.getMessage());
		} 
		catch (IllegalArgumentException ex) {
			Log.e(LOGTAG, ex.getMessage());
		} 
		catch(SQLiteException ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		catch(Exception ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		finally{
			if(db != null)
				if(db.isOpen()) db.close();
		}
		return result;
	}	
	
	public boolean Delete(int detailId) {
		boolean result = false;
		SQLiteDatabase db = null;
		String[] filter = new String[1];
		filter[0] = Long.toString(detailId);
		try{
			if(!_session.IsOpen())
				_session.Open();
			
			db = _session.Connection();
			int rows = db.delete(getTableName(), " id = ?", filter);
			result = (rows > 0) ? true : false;
			db.close();			
		}
		catch (SecurityException ex) {
			Log.e(LOGTAG, ex.getMessage());
		} 
		catch (IllegalArgumentException ex) {
			Log.e(LOGTAG, ex.getMessage());
		} 
		catch(SQLiteException ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		catch(Exception ex){
			Log.e(LOGTAG, ex.getMessage());
		}
		finally{
			if(db != null)
				if(db.isOpen()) db.close();
		}
		return result;
	}	
	
	
	@Override
	public String getTableName() {
		return "Orders_Details";
	}
	
	@Override
	public OrderDetail BuildNewEntity(Cursor cursor) {
		OrderDetail orderDetail = new OrderDetail();
		orderDetail.setId(cursor.getInt(0));
		Order order = _orderRepository.Get(cursor.getInt(1));		
		orderDetail.setOrder(order);
		Dish dish = _dishRepository.Get(cursor.getInt(2));
		orderDetail.setDish(dish);
		long miliseconds = cursor.getLong(3);
		Date date = new Date(miliseconds);		
		orderDetail.setDate(date);
		orderDetail.setStatus(cursor.getInt(4));
		orderDetail.setCookingPoint(cursor.getInt(5));
		
		return orderDetail;
	}
}
